home *** CD-ROM | disk | FTP | other *** search
- EXPRESSIONS
- The second major interpretation applied to strings in Tcl is
- as expressions. Several commands, such as expr, for, and
- if, treat one or more of their arguments as expressions and
- call the Tcl expression processors (Tcl_ExprLong,
- Tcl_ExprBoolean, etc.) to evaluate them. The operators
- permitted in Tcl expressions are a subset of the operators
- permitted in C expressions, and they have the same meaning
- and precedence as the corresponding C operators.
-
- Expressions almost always yield numeric results (integer or
- floating-point values). For example, the expression
-
- 8.2 + 6
-
- evaluates to 14.2. Tcl expressions differ from C
- expressions in the way that operands are specified, and in
- that Tcl expressions support non-numeric operands and string
- comparisons.
-
- A Tcl expression consists of a combination of operands,
- operators, and parentheses. White space may be used between
- the operands and operators and parentheses; it is ignored by
- the expression processor. Where possible, operands are
- interpreted as integer values. Integer values may be
- specified in decimal (the normal case), in octal (if the
- first character of the operand is 0), or in hexadecimal (if
- the first two characters of the operand are 0x). If an
- operand does not have one of the integer formats given
- above, then it is treated as a floating-point number if that
- is possible. Floating-point numbers may be specified in any
- of the ways accepted by an ANSI-compliant C compiler (except
- that the ``f'', ``F'', ``l'', and ``L'' suffixes will not be
- permitted in most installations). For example, all of the
- following are valid floating-point numbers: 2.1, 3., 6e4,
- 7.91e+16. If no numeric interpretation is possible, then an
- operand is left as a string (and only a limited set of
- operators may be applied to it).
-
- Operators may be specified in any of the following ways:
-
- [1]
- As an numeric value, either integer or floating-point.
-
- [2]
- As a Tcl variable, using standard $ notation. The
- variable's value will be used as the operand.
-
- [3]
- As a string enclosed in double-quotes. The expression
- parser will perform backslash, variable, and command
- substitutions on the information between the quotes,
- and use the resulting value as the operand
-
- [4]
- As a string enclosed in braces. The characters between
- the open brace and matching close brace will be used as
- the operand without any substitutions.
-
- [5]
- As a Tcl command enclosed in brackets. The command
- will be executed and its result will be used as the
- operand.
-
- [6]
- An unquoted string consisting of any number of letters,
- digits, and underscores (but a digit may not be the
- first character).
-
- Where substitutions occur above (e.g. inside quoted
- strings), they are performed by the expression processor.
- However, an additional layer of substitution may already
- have been performed by the command parser before the
- expression processor was called. As discussed below, it is
- usually best to enclose expressions in braces to prevent the
- command parser from performing substitutions on the
- contents.
-
- For some examples of simple expressions, suppose the
- variable a has the value 3 and the variable b has the value
- 6. Then the expression on the left side of each of the
- lines below will evaluate to the value on the right side of
- the line:
-
- 3.1 + $a 6.1
- 2 + "$a.$b" 5.6
- 4*[length "6 2"] 8
- {word one} < "word $a" 0
-
-
- The valid operators are listed below, grouped in decreasing
- order of precedence:
-
- - ~ !
- Unary minus, bit-wise NOT, logical NOT.
- None of these operands may be applied to
- string operands, and bit-wise NOT may be
- applied only to integers.
-
- * / %
- Multiply, divide, remainder. None of
- these operands may be applied to string
- operands, and remainder may be applied
- only to integers.
-
- + -
- Add and subtract. Valid for any numeric
- operands.
-
- << >>
- Left and right shift. Valid for integer
- operands only.
-
- < > <= >=
- Boolean less, greater, less than or
- equal, and greater than or equal. Each
- operator produces 1 if the condition is
- true, 0 otherwise. These operators may
- be applied to strings as well as numeric
- operands, in which case string
- comparison is used.
-
- == !=
- Boolean equal and not equal. Each
- operator produces a zero/one result.
- Valid for all operand types.
-
- &
- Bit-wise AND. Valid for integer
- operands only.
-
- ^
- Bit-wise exclusive OR. Valid for
- integer operands only.
-
- |
- Bit-wise OR. Valid for integer operands
- only.
-
- &&
- Logical AND. Produces a 1 result if
- both operands are non-zero, 0 otherwise.
- Valid for numeric operands only
- (integers or floating-point).
-
- ||
- Logical OR. Produces a 0 result if both
- operands are zero, 1 otherwise. Valid
- for numeric operands only (integers or
- floating-point).
-
- x?y:z
- If-then-else, as in C. If x evaluates
- to non-zero, then the result is the
- value of y. Otherwise the result is the
- value of z. The x operand must have a
- numeric value.
-
- See the C manual for more details on the results produced by
- each operator. All of the binary operators group left-to-
- right within the same precedence level. For example, the
- expression
-
- 4*2 < 7
-
- evaluates to 0.
-
- The &&, ||, and ?: operators have ``lazy evaluation'', just
- as in C, which means that operands are not evaluated if they
- are not needed to determine the outcome. For example, in
-
- $v ? [a] : [b]
-
- only one of [a] or [b] will actually be evaluated, depending
- on the value of $v.
-
- All internal computations involving integers are done with
- the C type long, and all internal computations involving
- floating-point are done with the C type double. When
- converting a string to floating-point, exponent overflow is
- detected and results in a Tcl error. For conversion to
- integer from string, detection of overflow depends on the
- behavior of some routines in the local C library, so it
- should be regarded as unreliable. In any case, overflow and
- underflow are generally not detected reliably for
- intermediate results.
-
- Conversion among internal representations for integer,
- floating-point, and string operands is done automatically as
- needed. For arithmetic computations, integers are used
- until some floating-point number is introduced, after which
- floating-point is used. For example,
-
- 5 / 4
- yields the result 1, while
-
- 5 / 4.0
- 5 / ( [length "abcd" chars] + 0.0 )
-
- both yield the result 1.25.
-
- String values may be used as operands of the comparison
- operators, although the expression evaluator tries to do
- comparisons as integer or floating-point when it can. If
- one of the operands of a comparison is a string and the
- other has a numeric value, the numeric operand is converted
- back to a string using the C sprintf format specifier %d for
- integers and %g for floating-point values. For example, the
- expressions
-
- "0x03" > "2"
- "0y" < "0x12"
- both evaluate to 1. The first comparison is done using
- integer comparison, and the second is done using string
- comparison after the second operand is converted to the
- string ``18''.
-
- In general it is safest to enclose an expression in braces
- when entering it in a command: otherwise, if the expression
- contains any white space then the Tcl interpreter will split
- it among several arguments. For example, the command
-
- expr $a + $b
-
- results in three arguments being passed to expr: $a, +, and
- $b. In addition, if the expression isn't in braces then the
- Tcl interpreter will perform variable and command
- substitution immediately (it will happen in the command
- parser rather than in the expression parser). In many cases
- the expression is being passed to a command that will
- evaluate the expression later (or even many times if, for
- example, the expression is to be used to decide when to exit
- a loop). Usually the desired goal is to re-do the variable
- or command substitutions each time the expression is
- evaluated, rather than once and for all at the beginning.
- For example, the command
-
- for {set i 1} $i<=10 {incr i} {...}*** WRONG ***
-
- is probably intended to iterate over all values of i from 1
- to 10. After each iteration of the body of the loop, for
- will pass its second argument to the expression evaluator to
- see whether or not to continue processing. Unfortunately,
- in this case the value of i in the second argument will be
- substituted once and for all when the for command is parsed.
- If i was 0 before the for command was invoked then for's
- second argument will be 0<=10 which will always evaluate to
- 1, even though i's value eventually becomes greater than 10.
- In the above case the loop will never terminate. Instead,
- the expression should be placed in braces:
-
- for {set i 1} {$i<=10} {incr i} {...}*** RIGHT ***
- This causes the substitution of i's value to be delayed; it
- will be re-done each time the expression is evaluated, which
- is the desired result.
-